package org.jrpc.client3;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoop;
import io.netty.channel.SimpleChannelInboundHandler;
import org.jrpc.base.IClient;
import org.jrpc.base.ResultResponse;
import org.jrpc.common.baen.RpcRequest;
import org.jrpc.common.baen.RpcResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * Created by chenyuncong on 2019/4/16.
 */
public class JrpcClientHandler extends SimpleChannelInboundHandler<RpcResponse> {
    private static final Logger logger = LoggerFactory.getLogger(JrpcClientHandler.class);
    private IClient iClient;

    private ConcurrentHashMap<String,ResultResponse> map;

    private ChannelHandlerContext ctx;

    public JrpcClientHandler(IClient iClient, ConcurrentHashMap<String,ResultResponse> map) {
        this.iClient = iClient;
        this.map=map;
    }

    public ResultResponse sendMsg(RpcRequest msg) throws IOException {
        ResultResponse resultResponse=new ResultResponse();
        map.put(msg.getRequestId(),resultResponse);
        ctx.channel().writeAndFlush(msg);
        return resultResponse;
    }

    /**
     * 监听重连
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.info("监听重连");
        final EventLoop eventLoop = ctx.channel().eventLoop();
        eventLoop.schedule((Runnable) () -> iClient.createBootstrap(new Bootstrap(), eventLoop), 1L, TimeUnit.SECONDS);
        super.channelInactive(ctx);
    }

    /**
     * 活动的通道
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//        super.channelActive(ctx);
        this.ctx = ctx;
    }

    /**
     * 数据返回触发
     * @param channelHandlerContext
     * @param rpcResponse
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, RpcResponse rpcResponse) throws Exception {
        ResultResponse res=map.get(rpcResponse.getRequestId());
        res.setRpcResponse(rpcResponse);
    }

    /**
     * 服务器断开触发
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception{
        //这里执行客户端断开连接后的操作
//        ctx.channel().close();
//        ctx.close();
        logger.info("=======服务端断开=======");
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("api caught exception", cause);
//        ctx.channel().close();
//        ctx.close();
        //重连接

    }



    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        super.userEventTriggered(ctx, evt);
    }
}
